class Snake{
    // 表示蛇头的元素
    head:HTMLElement;

    // 蛇的身体
    bodies:HTMLCollection;

    // 获取蛇的容器
    element: HTMLElement;

    constructor() {
        this.element = document.getElementById('snake')!;

        this.head = document.querySelector('#snake > div') as HTMLElement;

        this.bodies = this.element.getElementsByTagName("div")


    }

    get X(){
       return this.head.offsetLeft;
    }

    get Y(){
        return this.head.offsetTop;
    }

    set X(value){
        // 如果新值和旧值一样，则直接返回不修改
        if (this.X === value){
            return;
        }

        if (value <0 || value>290){
            throw new Error("蛇撞墙了")
        }

         // 修改x时，是在修改水平坐标，蛇在左右移动，蛇在向左移动时，不能向右掉头，反之亦然
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
            // console.log('水平方向发生了掉头');
            // 如果发生了掉头，让蛇向反方向继续移动
            if (value > this.X) {
                // 如果新值value大于旧值X，则说明蛇在向右走，此时发生掉头，应该使蛇继续向左走
                value = this.X - 10;
            } else {
                // 向左走
                value = this.X + 10;
            }
        }

        this.movebody()

        this.head.style.left = value + "px"

        this.checkHeadBody()



    }

    set Y(value){
        // 如果新值和旧值一样，则直接返回不修改
        if (this.Y === value){
            return;
        }
        if (value <0 || value>290){
            throw  new Error("蛇撞墙了")
        }

        // 修改y时，是在修改垂直坐标，蛇在上下移动，蛇在向上移动时，不能向下掉头，反之亦然
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
            if (value > this.Y) {
                value = this.Y - 10;
            } else {
                value = this.Y + 10;
            }
        }

        this.movebody()


        this.head.style.top = value + "px"

        this.checkHeadBody()


    }

    // 蛇增加身体
    addBody(){
        this.element.insertAdjacentHTML("beforeend","<div></div>")
    }

    //移动身体
    movebody(){
        for (let i = this.bodies.length-1; i>0;i--){
            let x = (this.bodies[i-1] as HTMLElement).offsetLeft;
            let y = (this.bodies[i-1] as HTMLElement).offsetTop;

            // 将该值设置到当前身体的值
            (this.bodies[i] as HTMLElement).style.left = x + 'px';
            (this.bodies[i] as HTMLElement).style.top = y + 'px';
        }
    }

    // 检查是否撞到自己
    checkHeadBody(){
         // 获取所有身体，检查其是否和蛇头坐标发生重叠
        for (let i=1; i<this.bodies.length; i++){
            let bd = this.bodies[i] as HTMLElement;
            if (this.X === bd.offsetLeft && this.Y === bd.offsetTop){
                throw new Error("撞到自己身体了")
            }
        }
    }
}

export default Snake;

